LambdaでNeptuneを停止する方法
こんにちは、ドイツのモナでございます〜
RDSと同じく、Amazon Neptuneは停止しても7日間が経ったら自動的に起動してしまうサービスです。なお、Neptuneの料金がそこそこ高いため、利用しない間はなるべく停止した状態が望ましいですね。もちろんスナップショットを作成し、以前使っていたDBを復元するといった手もありますが、今回はLambdaを使って、勝手に起動してしまったNeptuneのクラスターを停止する方法を紹介したいと思います。
準備
IAMポリシーとロールの作成
まず、権限系の準備が必要なのでIAMポリシーとロールを作りましょう。ここの注意ポイントは、サービスとして neptune
ではなく、 RDS
を選択する必要があります。
AWSサービスからIAMを選んで、ポリシーを作成をクリック
JSONタブをクリック、以下をコピペでも入力(ビジュアルエディタでもOK)
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "rds:StartDBCluster", "rds:StopDBCluster", "rds:DescribeDBClusters", "logs:CreateLogStream", "logs:CreateLogGroup", "logs:PutLogEvents" ], "Resource": "*" } ] }
ハイライトされている行が特に大事です。これがないと、Neptuneを停止することができません。
なお、"rds:StartDBCluster"
は今回は実は必要ないですが、停止だけでなくて、停止開始スケジューリングには便利なので入れておきました。
確認画面がこんな感じになっていればOKです!
作成したポリシーを使ってNeptuneを停止権限のあるロールも作りましょう。
先ほど作成したロールをアタッチ
確認、作成
これで準備が完了です〜
Lambda関数
本番としていよいよLambda関数の作成ですね。
まず、AWSサービスからLambdaを選択し、「関数の作成」をクリック
今回は一から作成します。ランタイムとしてPythonを使っていますが、お好みの言語でもできるはずです。
作成後の詳細設定は初期のままでも大丈夫ですが、念のためメモリを512MB、タイムアウトを15秒にしました。
なお、関数はこれだけのコードで動きます!
import os import botocore import boto3 from botocore.exceptions import ClientError def lambda_handler(event, context): neptune = boto3.client('neptune') lambdaFunc = boto3.client('lambda') print('Getting Environment variable') try: cluster = os.environ['ClusterIdentifier'] print("Stopping Neptune cluster: " + cluster) except ClientError as e: print("Couldn't get environment variable") raise e return {"message" : "Couldn't get environment variable"} try: response = neptune.stop_db_cluster(DBClusterIdentifier=cluster) print("Cluster stopped") except ClientError as e: if e.response['Error']['Code'] == 'InvalidDBClusterStateFault': print("Neptune cluster already in a stopped state.") else: raise e return {"message" : "Script execution completed. See Cloudwatch logs for complete output"}
停止したいNeptuneのクラスターを指定するのに関数の環境変数を設定しましょう。 直接関数に書いてしまってもいいのですが、環境変数の方が柔軟なので個人的にその方が好きです。
まずはクラスターIDをNeptune画面から確認
次にLambdaの環境変数を更新
これでLambda関数を使ってNeptuneを停止することができます!
ただし、まだ勝手に実行されるわけではないので、最後にLambda画面からトリガーを追加しましょう。
私は単純なcronジョブを使っていますが、ユースケースに合わせて適切なトリガーを設定することで停止の自動化が完了となります〜
まとめ・ポイント
- Neptuneは料金の高いサービスなので利用しない間に停止することをおすすめします。Neptuneサービスにおける自動開始をLambdaを使って押さえましょう。
- クラスターのAPI操作としては
neptune.stop_db_cluster
を利用します。 - IAMポリシーとしては
neptune:*
ではなく、rds:*
を指定する必要があります。 ← ここが一番ハマりやすいポイントだと思います!